// 5.cpp

#include "exercise.h"

const static unsigned int revoTimer = 1;
const static GLfloat revoRadius = 14.0f;
const static GLfloat revoMoonRadius = 5.0f;


class scene5 : public exerciseScene
{
public:
    scene5();
    virtual void setupScene();
    virtual void cleanScene();
    virtual void renderScene();
    virtual void timer(unsigned int id);

private:
    void setLight0();
    void setMaterialSun();
    void setMaterialEarth();
    void setMaterialMoon();

    GLfloat angleRove;
    GLfloat angleMoon;
};

scene5::scene5() :
    angleRove(0.0f), angleMoon(0.0f)
{

}

void scene5::setupScene()
{
    if (wnd)
    {
        wnd->resetViewport();
        wnd->startTimer(revoTimer, 50);
    }

    setLight0();

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
}

void scene5::cleanScene()
{
    if (wnd)
    {
        wnd->stopTimer(revoTimer);
    }
    glDisable(GL_LIGHT0);
    glDisable(GL_LIGHTING);
}

void scene5::renderScene()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-30.0, 30.0, -30.0, 30.0, 0.0, 30.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 30.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);

    // sun
    //glColor3f(1.0f, 1.0f, 0.0f);
    setMaterialSun();
    exerciseSphere sun(4.0, 3);
    sun.render();

    glRotatef(angleRove, 0.0, 1.0, 0.0);
    glTranslatef(revoRadius, 0.0, 0.0);


    //glColor3f(0.3f, 0.3f, 0.3f);
    setMaterialEarth();
    exerciseSphere earth(2.0, 3);
    earth.render();


    glRotatef(angleMoon, 0.0, 1.0, 0.0);
    glTranslatef(revoMoonRadius, 0.0, 0.0);

    setMaterialMoon();
    exerciseSphere moon(1.5, 3);
    moon.render();
}

void scene5::timer(unsigned int id)
{
    if (id == revoTimer)
    {
        angleRove += 2.0f;
        if (angleRove >= 360.0)
            angleRove -= 360;

        angleMoon += 2.0f;
        if (angleMoon >= 360.0)
            angleMoon -= 360.0;

        if (wnd)
            wnd->postRedisplay();
    }
}

void scene5::setLight0()
{
    GLfloat ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat diffuse[] = {1.0f, 0.0f, 0.0f, 1.0f};
    GLfloat specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat position[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat ambientModel[] = {0.0f, 0.0f, 0.0f, 1.0f};
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0f);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientModel);
}

void scene5::setMaterialSun()
{
    GLfloat ambient[] = {0.7f, 0.7f, 0.0f, 1.0f};
    GLfloat diffuse[] = {0.7f, 0.7f, 0.0f, 1.0f};
    GLfloat specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat shininess = 0.0f;
    GLfloat emission[] = {0.2f, 0.2f, 0.0f, 1.0f};
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT, GL_SHININESS, shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, emission);
}

void scene5::setMaterialEarth()
{
    GLfloat ambient_diffuse[] = {1.0f, 0.5f, 1.0f, 1.0f};
    GLfloat specular[] = {0.1f, 0.1f, 0.1f, 1.0f};
    GLfloat shininess = 0.0f;
    GLfloat emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ambient_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT, GL_SHININESS, shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, emission);
}

void scene5::setMaterialMoon()
{
    GLfloat ambient_diffuse[] = {0.5f, 0.5f, 0.5f, 1.0f};
    GLfloat specular[] = {0.1f, 0.1f, 0.1f, 1.0f};
    GLfloat shininess = 135.0f;
    GLfloat emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ambient_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT, GL_SHININESS, shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, emission);
}

exerciseScene* createScene5()
{
    return new scene5;
}